# ifndef WINDOW_MGR_H
# define WINDOW_MGR_H
#include <iostream>
#include <vector>
#include "Screen.h"
using std::cerr, std::clog;
using std::cin, std::cout, std::endl;
using std::string;

// 类数据成员的初始值
// 默认情况下，我们希望Window_mgr类开始时总是拥有一个默认初始化的Screen。
// 在C++11新标准中，最好的方式就是把这个默认值声明成一个类内初始值
class Window_mgr
{
public:
    // 窗口中每个屏幕的编号
    using ScreenIndex = std::vector<Screen>::size_type;
    // 按照编号将指定的Screen重置为空白
    void clear(ScreenIndex);
    // 向窗口添加一个Screen，返回它的编号
    ScreenIndex addScreen(const Screen &s);
private:
    // 这个Window_mgr追踪的Screen
    // 默认情况下，一个Window_mgr包含一个标准尺寸的空白Screen
    std::vector<Screen> screens{Screen(24, 80, ' ')}; // 类数据成员的初始值，类内初始值
    // 如我们之前所知的，类内初始值必须使用=的初始化形式（初始化Screen的数据成员时所用的）
    // 或者花括号括起来的直接初始化形式（初始化screens所用的）。

    // 当我们提供一个类内初始值时，必须以符号=或者花括号表示。
};

// 必须要注意的一点是，友元关系不存在传递性。
// 也就是说，如果Window_mgr有它自己的友元，则这些友元并不能理所当然地具有访问Screen的特权。
void Window_mgr::clear(ScreenIndex i)
{
    // s是个引用，指向我们想清空的那个屏幕
    Screen &s = screens[i];
    // 当Screen将Window_mgr指定为其友元之后，Screen的所有成员对于Window_mgr就都变成可见的了。
    s.contents = string(s.height * s.width, ' '); //将选定的Screen重置为空白
}

// 当成员函数定义在类的外部时，返回类型中使用的名字都位于类的作用域之外。这时，返回类型必须指明它是哪个类的成员。
// 当在7.4.cc中同时包含Screen.h和WindowMgr.h时，该函数报错：
// declaration is incompatible with "Window_mgr::ScreenIndex Window_mgr::addScreen(const <error-type> &s)" (declared at line 44 of "D:\MYSTUDY\C++\C++PRIMER5\CHATPER07\WindowMgr.h")C/C++(147)
Window_mgr::ScreenIndex Window_mgr::addScreen(const Screen &s)
{
    screens.push_back(s);
    return screens.size() - 1;
}



#endif